package cn.iocoder.yudao.module.erp.service.deppurchase;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.erp.controller.admin.deppurchase.vo.DepPurchasePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.deppurchase.vo.DepPurchaseRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.deppurchase.vo.DepPurchaseSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.deppurchaseitem.vo.DepPurchaseItemPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.deppurchase.DepPurchaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.deppurchaseitem.DepPurchaseItemDO;
import cn.iocoder.yudao.module.erp.dal.mysql.deppurchase.DepPurchaseMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.deppurchaseitem.DepPurchaseItemMapper;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.DEPT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.DEP_PURCHASE_NOT_EXISTS;

/**
 * ERP 科室采购申请单 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class DepPurchaseServiceImpl implements DepPurchaseService {

    @Resource
    private DepPurchaseMapper depPurchaseMapper;
    @Resource
    private DepPurchaseItemMapper depPurchaseItemMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private DeptMapper deptMapper;
    /**
     * 采购申请对应的流程定义KEY
     */
    @Value("${erp.department.processKey:dep_purchase}")
    private String PROCESS_KEY;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createDepPurchase(Long userId, DepPurchaseSaveReqVO createReqVO) {

        // 发起人信息
        AdminUserRespDTO user = adminUserApi.getUser(userId);
        Long deptId = user.getDeptId();
        createReqVO.setDeptId(deptId);
        if (StringUtils.isEmpty(createReqVO.getOrderId())) {
            createReqVO.setOrderId(UUID.randomUUID().toString());
        }
        // 插入
        DepPurchaseDO depPurchase = BeanUtils.toBean(createReqVO, DepPurchaseDO.class);
        depPurchaseMapper.insert(depPurchase);
        if (createReqVO != null) {
            List<DepPurchaseItemDO> depPurchaseItems = createReqVO.getDepPurchaseItems();
            for (DepPurchaseItemDO depPurchaseItemDO : depPurchaseItems) {
                depPurchaseItemDO.setDeptId(deptId);
            }
            createReqVO.setDepPurchaseItems(depPurchaseItems);
        }
        // 插入子表
        createDepPurchaseItemList(depPurchase.getId(), createReqVO.getDepPurchaseItems());
        // 返回
        return depPurchase.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void fenfacreateDepPurchase(Long userId, DepPurchaseSaveReqVO updateReqVO) {
        // 修改采购单信息
        // 校验存在
        validateDepPurchaseExists(updateReqVO.getId());
        // 更新
        DepPurchaseDO updateObj = BeanUtils.toBean(updateReqVO, DepPurchaseDO.class);
        depPurchaseMapper.updateById(updateObj);
        updateDepPurchaseItemList(updateReqVO.getId(), updateReqVO.getDepPurchaseItems());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDepPurchase(DepPurchaseSaveReqVO updateReqVO) {
        // 校验存在
        validateDepPurchaseExists(updateReqVO.getId());
        // 更新
        DepPurchaseDO updateObj = BeanUtils.toBean(updateReqVO, DepPurchaseDO.class);
        depPurchaseMapper.updateById(updateObj);

        // 更新子表
        updateDepPurchaseItemList(updateReqVO.getId(), updateReqVO.getDepPurchaseItems());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(String integraId) {

        depPurchaseMapper.updateStatus(integraId);


    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDepPurchase(Long id) {
        // 校验存在
        validateDepPurchaseExists(id);
        // 删除
        depPurchaseMapper.deleteById(id);

        // 删除子表
        deleteDepPurchaseItemByOrderId(id);
    }

    private void validateDepPurchaseExists(Long id) {
        if (depPurchaseMapper.selectById(id) == null) {
            throw exception(DEP_PURCHASE_NOT_EXISTS);
        }
    }

    @Override
    public DepPurchaseRespVO getDepPurchase(Long id) {
        DepPurchaseDO depPurchase = depPurchaseMapper.selectById(id);
        DepPurchaseRespVO depPurchaseRespVO = BeanUtils.toBean(depPurchase, DepPurchaseRespVO.class);
        List<DepPurchaseItemDO> depPurchaseItemDOS = depPurchaseItemMapper.selectListByOrderId(id);
        depPurchaseRespVO.setDepPurchaseItems(depPurchaseItemDOS);
//        将部门名设置到 depPurchaseRespVO
        DeptDO deptDO = deptMapper.selectById(depPurchaseRespVO.getDeptId());
        // 非空检验
        if (deptDO == null) {
            throw exception(DEPT_EXISTS);
        }
        depPurchaseRespVO.setDeptName(deptDO.getName());
        return depPurchaseRespVO;
    }

    @Override
    public PageResult<DepPurchaseDO> getDepPurchasePage(DepPurchasePageReqVO pageReqVO) {
        return depPurchaseMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（ERP 科室采购申请项） ====================

    @Override
    public List<DepPurchaseItemDO> getDepPurchaseItemListByOrderId(Long orderId) {
        return depPurchaseItemMapper.selectListByOrderId(orderId);
    }

    @Override
    public List<DepPurchaseItemDO> getnewDepPurchaseItemListByOrderId(Long orderId) {
        return depPurchaseItemMapper.selectByOrderId(orderId);
    }


    @Override
    public List<DepPurchaseItemDO> getDepPurchaseItemList(DepPurchaseItemPageReqVO pageReqVO) {
        String integraId = pageReqVO.getIntegrateId();
        Long supplierId = pageReqVO.getSupplierId();
        Long productUnitId = pageReqVO.getProductUnitId();
        String productName = pageReqVO.getProductName();
        String productStandards = pageReqVO.getProductStandards();
        List<DepPurchaseItemDO> depPurchaseItemList = depPurchaseItemMapper.getDepPurchaseItemList(integraId, supplierId, productUnitId, productName, productStandards);
        return depPurchaseItemList;
    }


    private void createDepPurchaseItemList(Long orderId, List<DepPurchaseItemDO> list) {
        list.forEach(o -> o.setOrderId(orderId));
        depPurchaseItemMapper.insertBatch(list);
    }

    private void updateDepPurchaseItemList(Long orderId, List<DepPurchaseItemDO> list) {
        deleteDepPurchaseItemByOrderId(orderId);
        list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createDepPurchaseItemList(orderId, list);
    }

    private void deleteDepPurchaseItemByOrderId(Long orderId) {
        depPurchaseItemMapper.deleteByOrderId(orderId);
    }

    @Override
    public void submit(Long userId, DepPurchaseSaveReqVO createReqVO) {
        /**
         * ---------------------------------------将业务插入到工作流程表中测试-------------------------------------------------------*/
        if (!StringUtils.isEmpty(PROCESS_KEY)) {
            // 发起 BPM 流程  加这里
            Map<String, Object> processInstanceVariables = new HashMap<>();
            String processInstanceId = processInstanceApi.createProcessInstance(userId,
                    new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                            .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(createReqVO.getId()))
                            .setStartUserSelectAssignees(createReqVO.getStartUserSelectAssignees()));

            // 将工作流的编号，更新到业务数据中
            depPurchaseMapper.updateById(new DepPurchaseDO().setId(createReqVO.getId()).setProcessInstanceId(processInstanceId));

        }
        /**-------------------------------------------------------------------------------------------------------------*/
    }

    @Override
    public void updateStatusByIntegraId(String integraId, Integer status) {
        depPurchaseMapper.updateStatusByIntegraId(integraId,status);
    }
}